package com.techysky.repository.impl;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.transform.Transformers;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import com.techysky.repository.CustomRepository;

@Transactional
@Repository
public class CustomRepositoryImpl implements CustomRepository {
	
	/** * */
	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(CustomRepositoryImpl.class);
	@PersistenceContext
	transient EntityManager entityManager;

	/**
	 * * * 查询数据集合 * @param sql 查询sql sql中的参数用:name格式 * @param params
	 * 查询参数map格式，key对应参数中的:name * @param clazz 实体类型为空则直接转换为map格式 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Map<String, Object>> queryListEntity(String sql, Map<String, Object> params) {
		Session session = entityManager.unwrap(org.hibernate.Session.class);
		SQLQuery query = session.createSQLQuery(sql);
		if (params != null) {
			for (Map.Entry<String, Object> map : params.entrySet()) {
				query.setParameter(map.getKey(), map.getValue());
			}
		}
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List<Map<String, Object>> result = query.list();
		return convert(result);
	}

	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> queryListEntity(String sql, Pageable page) {
		Session session = entityManager.unwrap(org.hibernate.Session.class);
		SQLQuery query = session.createSQLQuery(sql);
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List<Map<String, Object>> result = query.setFirstResult(page.getPageNumber()).setMaxResults(page.getPageSize())
				.list();
		return convert(result);
	}

	private List<Map<String, Object>> convert(List<Map<String, Object>> list) {
		List<Map<String, Object>> result = new ArrayList<>();
		try {
			for (Map<String, Object> map : list) {
				Map<String, Object> map1 = new HashMap<>();
				for (Map.Entry<String, Object> m : map.entrySet()) {
					map1.put(m.getKey().toLowerCase(), m.getValue());
				}
				result.add(map1);
			}
		} catch (Exception e) {
			log.info(e);
		}
		return result;
	}

	/**
	 * 获取记录条数
	 * @param sql
	 * @param params
	 * @return
	 */
	public Integer getCountBy(String sql, Map<String, Object> params) {
		Query query = entityManager.createNativeQuery(sql);
		if (params != null) {
			for (Map.Entry<String, Object> map : params.entrySet()) {
				query.setParameter(map.getKey(), map.getValue());
			}
		}
		BigInteger bigInteger = (BigInteger) query.getSingleResult();
		return bigInteger.intValue();
	}

	@SuppressWarnings("rawtypes")
	public Integer getCountBy(String sql) {
		Session session = entityManager.unwrap(org.hibernate.Session.class);
		SQLQuery query = session.createSQLQuery(sql);
		List list = query.list();
		if (list.isEmpty())
			return Integer.valueOf(list.get(0).toString());
		return new Integer(0);
	}

	/** * 新增或者删除 * @param sql * @param params * @return */
	public Integer deleteOrUpDate(String sql, Map<String, Object> params) {
		Query query = entityManager.createNativeQuery(sql);
		if (params != null) {
			for (Map.Entry<String, Object> map : params.entrySet()) {
				query.setParameter(map.getKey(), map.getValue());
			}
		}
		return query.executeUpdate();
	}
	
	@SuppressWarnings("rawtypes")
	@Override
	public List queryResultMap(String jql) {
		Query query = entityManager.createQuery(jql);
		return query.getResultList();
	}
	
	
	
	

	@Override
	public List getDbList(String sql) {
		Query query = entityManager.createNativeQuery(sql);
		return query.getResultList();
	}
	
	

	@Override
	public void cleanDb(String sql) {
		Query query = entityManager.createNativeQuery(sql);
		query.executeUpdate();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Page queryPageResultMap(String jql, Pageable pageable) {
		return new PageImpl(queryListEntity(jql, pageable), pageable,
				getCountBy("select count(*) " + jql.substring(jql.indexOf("from"))));
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Page queryPageResultMapByJql(String jql, Pageable pageable) {
		long total = Long.parseLong(entityManager.createQuery("select count(*) " + jql.substring(jql.indexOf("from")))
				.getSingleResult().toString());
		List content = entityManager.createQuery(jql).setFirstResult(pageable.getPageNumber())
				.setMaxResults(pageable.getPageSize()).getResultList();
		return new PageImpl(content, pageable, total);
	}
}